/**
 * 
 */
package com.cooksys.film_rental.dao;

import java.util.List;

import com.cooksys.film_rental.model.Address;
import com.cooksys.film_rental.model.Customer;
import com.cooksys.film_rental.model.Film;
import com.cooksys.film_rental.model.Payment;
import com.cooksys.film_rental.model.Rental;
import com.cooksys.film_rental.model.Store;
import com.cooksys.film_rental.model.User;

/**
 * Data access object for the {@link Customer} class
 * 
 * @author Peter Zastoupil
 * 
 */
public interface CustomerDao {

	/**
	 * Saves a given {@link Customer} as a record in the database
	 * 
	 * @param customer
	 *            the Customer to save
	 * @return the {@link Customer} that was saved
	 */
	public Customer save(Customer customer);

	/**
	 * Updates the database record associated with the given {@link Customer}
	 * 
	 * @param customer
	 *            the Customer to be updated
	 */
	public void update(Customer customer);

	/**
	 * Deletes the database record associated with the given {@link Customer}
	 * 
	 * @param customer
	 *            the Customer to be deleted
	 */
	public void delete(Customer customer);

	/**
	 * 
	 * @param customerId
	 *            the customerId to search by
	 * @return a {@link Customer} object that corresponds to the given
	 *         customerId
	 */
	public Customer getCustomerByCustomerId(Short customerId);

	/**
	 * 
	 * @param adress
	 *            the {@link Address} to search by
	 * @return a List of {@link Customer} objects associated with the given
	 *         address
	 */
	public List<Customer> searchCustomersByAddress(Address address);

	/**
	 * 
	 * @param store
	 *            the {@link Store} to search by
	 * @return a List of {@link Customer} objects associated with the given
	 *         store
	 */
	public List<Customer> searchCustomersByStore(Store store);

	/**
	 * 
	 * @param partialName
	 *            a String that contains search terms separated by whitespace
	 * @return a List of {@link Customer} objects that that match the given
	 *         partial name
	 */
	public List<Customer> searchCustomersByPartialName(String partialName);

	/**
	 * 
	 * @param user
	 *            the {@link User} to search by
	 * @return the {@link Customer} object associated with the given user
	 */
	public Customer getCustomerByUser(User user);

	/**
	 * 
	 * @param rental
	 *            the {@link Rental} to search by
	 * @return the {@link Customer} object associated with the given rental
	 */
	public Customer getCustomerByRental(Rental rental);

	/**
	 * 
	 * @param payment
	 *            the {@link Payment} to search by
	 * @return the {@link Customer} associated with the given payment
	 */
	public Customer getCustomerByPayment(Payment payment);

	/**
	 * 
	 * @param customer
	 *            the {@link Customer} to save or update
	 */
	public void saveOrUpdate(Customer customer);

	/**
	 * 
	 * @param firstName
	 *            the first name associated with the customer
	 * @param lastName
	 *            the last name associated with the customer
	 * @param email
	 *            the email associated with the customer
	 * @param address
	 *            the {@link Address} associated with the customer
	 * @param store
	 *            the {@link Store} associated with the customer
	 * @return a {@link Customer} object from the database that matches the
	 *         input values
	 */
	public Customer getCustomerByInfoAndAddressAndStore(String firstName,
			String lastName, String email, Address address, Store store);

	/**
	 * 
	 * @param customer
	 *            the {@link Customer} who has added the desired films to his or
	 *            her cart
	 * @return a List of {@link Film} objects that represent inventory items the
	 *         given customer has added to the cart, but not checked out. That
	 *         is to say, a list of films that have inventory records associated
	 *         with the given customer that are associated with rental records
	 *         that have no return date or payment records in the database
	 */
	public List<Film> getFilmsInCart(Customer customer);

	/**
	 * 
	 * @param customer
	 *            the {@link Customer} whose rented films are desired
	 * @return a List of {@link Film} object that the given customer has
	 *         actually rented. That is to say, a list of films that have
	 *         inventory records associated with the given customer that are
	 *         associated with rental records that have no return date but do
	 *         have associated payment records in the database
	 */
	List<Film> getRentedFilms(Customer customer);

	/**
	 * 
	 * @param customer
	 *            the {@link Customer} to get the rentals in cart for
	 * @return a List of {@link Rental} objects associated with the customer
	 *         that have no return date or payment associated with them
	 */
	public List<Rental> getRentalsInCart(Customer customer);

	/**
	 * 
	 * @param customer
	 *            the {@link Customer} to get the paid rentals for
	 * @return a List of {@link Rental} objects associated with the customer
	 *         that have no return date but do have a payment record associated
	 *         with them
	 */
	List<Rental> getPaidRentals(Customer customer);

}
